package com.yjd.pub.project.service;

import com.alibaba.fastjson.JSON;
import com.yjd.comm.annotation.ServiceRemoteProxy;
import com.yjd.comm.base.dao.IBaseDao;
import com.yjd.comm.base.enums.DbWREnums;
import com.yjd.comm.base.model.IntroDetailModel;
import com.yjd.comm.base.model.PagerModel;
import com.yjd.comm.base.service.impl.BaseServiceImpl;
import com.yjd.comm.enums.ReferenceTypeEnum;
import com.yjd.comm.merchant.model.MerchantChangeLogsModel;
import com.yjd.comm.merchant.service.IMerchantChangeLogsService;
import com.yjd.comm.org.model.OrganizationModel;
import com.yjd.comm.org.service.IOrganizationService;
import com.yjd.comm.project.model.*;
import com.yjd.comm.project.service.IPrjCategoryService;
import com.yjd.comm.project.service.IProjectService;
import com.yjd.comm.system.util.SysParamUtil;
import com.yjd.comm.tag.model.TagInfoDto;
import com.yjd.comm.tag.service.ITagRelevanceService;
import com.yjd.comm.tag.service.ITagService;
import com.yjd.comm.util.*;
import com.yjd.comm.vo.Constant;
import com.yjd.pub.base.dao.IIntroDetailDao;
import com.yjd.pub.project.dao.IProjectDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <b>description</b>：项目业务实现<br>
 * <b>time</b>：2017-06-27 08:55:08 <br>
 * <b>author</b>：  yangchangyan@yijiedai.com
 */
@Service("projectService")
public class ProjectServiceImpl extends BaseServiceImpl implements IProjectService {

    /**
     * 插入
     *
     * @param model
     * @return
     * @throws Exception
     */
    public ProjectModel insert(ProjectModel model) throws Exception {
        return this.projectDao.insertModel(model, true);
    }

    /**
     * 更新
     *
     * @param model
     * @return
     * @throws Exception
     */
    public int update(ProjectModel model) throws Exception {
        return this.projectDao.updateModel(model, true);
    }

    @Override
    public int createOrUpdate(ProjectModel pm, String projectDetail, String[] tags) throws Exception {

        Long currentTime = FrameUtil.getTime();
        // 创建项目详情
        IntroDetailModel detail = new IntroDetailModel();
        detail.setContent(projectDetail);
        detail.setRef_type(ReferenceTypeEnum.PROJECT.getCode());
        detail.setLast_update_time(currentTime);

        IntroDetailModel m = introDetailDao.getModelById(pm.getDetail_id(), false);
        if(pm.getDetail_id() == null || introDetailDao.getModelById(pm.getDetail_id(), false) == null){
            detail.setCreate_time(currentTime);
            detail = introDetailDao.insertModel(detail, true);
        }else{
            detail.setDetail_id(pm.getDetail_id());
            introDetailDao.updateModel(detail, true);
        }

        // 创建项目基本信息
        if(null == pm.getIs_used()){
            pm.setIs_used(0); // 默认不启用
        }
        if(null == pm.getIs_spread()){
            pm.setIs_spread(0); // 默认不推广
        }
        if(StringUtil.isEmpty(pm.getRate_config())){
            OrganizationModel om = organizationService.getModelById(pm.getOrg_id(), DbWREnums.WRITE);
            List<Integer> periodsList  = StringUtil.getObject(om.getLimit_config(), List.class);
            Constant.SysParamKeyEnum sysParamKeyEnum = null;
            Map rateMap = new HashMap();
            for(Integer limit : periodsList){
                sysParamKeyEnum = StagesRateUtils.getSysParamKeyEnum(limit);
                if(null == sysParamKeyEnum){
                    rateMap.put(limit+"", "0.0");
                }else{
                    rateMap.put(limit+"", SysParamUtil.getValue(sysParamKeyEnum));
                }
            }
            pm.setRate_config(JSON.toJSONString(rateMap));
        }

        if(pm.getIs_spread().intValue()==1){
            if(pm.getProject_price()==null||pm.getProject_price().intValue()==0){
                FrameUtil.throwBaseException1("推广项目必须输入项目价格");
            }

            if(pm.getAct_price()==null||pm.getAct_price().intValue()==0){
                FrameUtil.throwBaseException1("推广项目必须输入活动价格");
            }
        }

        pm.setPayment(ArithUtil.sub(pm.getAct_price(), pm.getLoan_price()));
        pm.setDetail_id(detail.getDetail_id());
        pm.setLast_update_time(currentTime);
        if(null == pm.getProject_id()){
            pm.setCreate_time(currentTime);
            pm = this.projectDao.insertModel(pm, true);
        }else{
            this.projectDao.updateModel(pm, true);
        }

        if(null != tags && tags.length > 0) {
            tagRelevanceService.updateTagRelevance(tags, pm.getProject_id(), ReferenceTypeEnum.PROJECT);
        }

        return 1;
    }

    @Override
    public int updateById(Long projectId, Map<Object, Object> paramMap) throws Exception {
        paramMap.put("project_id", projectId);
        return projectDao.updateByMap(paramMap, true);
    }

    /**
     * 根据id删除
     *
     * @param project_id
     * @return
     * @throws Exception
     */
    public int delete(long project_id) throws Exception {
        Map<Object, Object> paramMap = new HashMap<Object, Object>();
        paramMap.put("project_id", project_id);
        return this.projectDao.deleteModel(paramMap, true);
    }

    /**
     * 搜索项目
     *
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    public PagerModel getProjectListByKeys(Map<String, Object> param) throws Exception {
        return this.getPageModel(param, "getProjectListByKeys", DbWREnums.READ);
    }


    @Override
    public int updateByMap(Map<Object, Object> param) throws Exception {
        return projectDao.updateByMap(param, true);
    }

    @Override
    public List<Map<String, Object>> queryProject(Map<String, Object> queryParamMap) throws Exception {
        queryParamMap.put("is_used", "1");
        List<Map<String, Object>> projects = new ArrayList<>();
        PagerModel projectPage = this.getPageModel(queryParamMap, DbWREnums.READ);
        for (Object obj : projectPage.getDataList()) {
            projects.add(this.transformToMap((ProjectModel) obj));
        }
        return projects;
    }

    @Override
    public Map<String, Object> transformProjectToMap(ProjectModel model) throws Exception {
        return transformToMap(model);
    }

    /**
     * 查询多个项目 根据idlist (项目id)
     *
     * @param list
     * @return
     * @throws Exception
     */
    @Override
    public Map<Long, ProjectShowInfo> getProjectInfoList(List<Long> list) throws Exception {
        Map<Long, ProjectShowInfo> mapList = new HashMap<Long, ProjectShowInfo>();
        List<ProjectShowInfo> prjList = projectDao.getProjectInfoList(list);
        for (ProjectShowInfo showInfo : prjList) {
            mapList.put(showInfo.getProject_id(), showInfo);
        }

        return mapList;
    }

    private Map<String, Object> transformToMap(ProjectModel pm) throws Exception {
        Map<String, Object> projectResult = ResultMapBuilder.build(pm);

        OrganizationModel org = organizationService.getModelById(pm.getOrg_id(), DbWREnums.READ);
        projectResult.put("org_name", null == org ? "" : org.getOrg_name());
        projectResult.put("org_mold", org.getOrg_mold());

        projectResult.put("org_address", null == org ? "" : CityUtil.getFullCityNames(org.getOrg_city(), "") + org.getOrg_address());

        PrjCategoryModel cgy = prjCategoryService.getModelById(pm.getCategory_id(), DbWREnums.READ);
        projectResult.put("category_name", null == cgy ? "" : cgy.getName());

        // 查找相关联的tag
        List<Long> refIdList = new ArrayList<Long>();
        refIdList.add(pm.getProject_id());
        List<TagInfoDto> allTagList = tagService.getTagNameList(FrameUtil.newHashMap("ref_type", ReferenceTypeEnum.PROJECT.getCode(), "idList", refIdList));
        List<String> tags = new ArrayList<String>();
        for (TagInfoDto t : allTagList) {
            tags.add(t.getTag_name());
        }
        projectResult.put("tags", tags);

        return projectResult;
    }


    /**
     * 商户上架项目
     *
     * @param project_id
     * @return
     * @throws Exception
     */
    @Override
    public int openProject(Long org_id,Long project_id) throws Exception {
        if (project_id == null||org_id==null) {
            FrameUtil.throwBaseException1("请求参数不能为空");
        }

        ProjectModel projectModel = projectDao.getModelById(project_id, true);
        if (projectModel == null) {
            FrameUtil.throwBaseException1("请求的记录不存在！");
        }

        if(projectModel.getOrg_id().intValue()!=org_id.intValue()){
            FrameUtil.throwBaseException1("该项目不属于当前机构");
        }

        Long currtime = FrameUtil.getTime(null);
        if (projectDao.updateByMap(FrameUtil.newHashMap("project_id", project_id, "is_used", 1, "last_update_time", currtime), true) != 1) {
            FrameUtil.throwBaseException1("上架失败！");
        }
        merchantChangeLogsService.insert(new MerchantChangeLogsModel(projectModel.getOrg_id(), "商户上架项目，项目id：" + project_id, currtime));
        return 1;
    }

    /**
     * 商户下架项目
     *
     * @param project_id
     * @return
     * @throws Exception
     */
    @Override
    public int colseProject(Long org_id,Long project_id) throws Exception {
        if (project_id == null||org_id==null) {
            FrameUtil.throwBaseException1("请求参数不能为空");
        }

        ProjectModel projectModel = projectDao.getModelById(project_id, true);
        if (projectModel == null) {
            FrameUtil.throwBaseException1("请求的记录不存在！");
        }

        if(projectModel.getOrg_id().intValue()!=org_id.intValue()){
            FrameUtil.throwBaseException1("该项目不属于当前机构");
        }

        Long currtime = FrameUtil.getTime(null);
        if (projectDao.updateByMap(FrameUtil.newHashMap("project_id", project_id, "is_used", 0, "last_update_time", currtime), true) != 1) {
            FrameUtil.throwBaseException1("下架失败！");
        }
        merchantChangeLogsService.insert(new MerchantChangeLogsModel(projectModel.getOrg_id(), "商户下架项目，项目id：" + project_id, currtime));
        return 1;
    }

    /**
     * 商户修改价格
     *
     * @param project_id
     * @param project_price 项目原价
     * @param act_price     实际售卖价格
     * @param payment       首付金额
     * @return
     * @throws Exception
     */
    @Override
    public int updateProjectPrice(Long org_id,Long project_id, Double project_price, Double act_price, Double payment,ProjectRateConfig projectRateConfig) throws Exception {
        if (project_id == null||org_id==null) {
            FrameUtil.throwBaseException1("请求参数不能为空");
        }

        if (project_price == null) {
            FrameUtil.throwBaseException1("原价不能为空");
        }

        if (project_price <= 0) {
            FrameUtil.throwBaseException1("原价不能小于等于0");
        }

        if (act_price <= 0) {
            FrameUtil.throwBaseException1("售卖价不能小于等于0");
        }

        if (project_price < act_price) {
            FrameUtil.throwBaseException1("原价不能小于售卖价");
        }

        if (payment < 0) {
            FrameUtil.throwBaseException1("首付金额不能小于0");
        }

        if (projectRateConfig == null) {
            FrameUtil.throwBaseException1("利率不能为空");
        }

        ProjectModel projectModel = projectDao.getModelById(project_id, true);
        if (projectModel == null) {
            FrameUtil.throwBaseException1("请求的记录不存在！");
        }

        if(projectModel.getOrg_id().intValue()!=org_id.intValue()){
            FrameUtil.throwBaseException1("该项目不属于当前机构");
        }


        List<ProjectRateModel> rateList = projectRateConfig.getRateList();
        Map rateMap = new HashMap();
        for (ProjectRateModel model : rateList) {
            if (model.getRate() == null || model.getRate().intValue() == 0) {
                FrameUtil.throwBaseException1("请配置" + model.getLimit() + "期数利率");
            }
            rateMap.put(model.getLimit().toString(), model.getRate().toString());
        }

        Long currtime = FrameUtil.getTime(null);
        if (projectDao.updateByMap(FrameUtil.newHashMap("project_id", project_id, "project_price", project_price, "act_price", act_price, "payment", payment,
                "loan_price", ArithUtil.sub(act_price,payment), "rate_config",JSON.toJSONString(rateMap),"last_update_time", currtime), true) != 1) {
            FrameUtil.throwBaseException1("更新价格信息失败！");
        }
        merchantChangeLogsService.insert(new MerchantChangeLogsModel(projectModel.getOrg_id(),
                "商户更新价格，项目id：" + project_id + "  项目原价：" + project_price + " 售卖价:" + act_price +
                        " 首付金额:" + payment+"  利率配置： "+JSON.toJSONString(rateMap), currtime));
        return 1;
    }

    /**
     * 商户修改利率配置
     *
     * @param project_id
     * @param config
     * @return
     * @throws Exception
     */
    @Override
    public int updateProjecRate(Long org_id,Long project_id, ProjectRateConfig config) throws Exception {
        if (project_id == null||org_id==null) {
            FrameUtil.throwBaseException1("请求参数不能为空");
        }

        if (config == null) {
            FrameUtil.throwBaseException1("利率不能为空");
        }

        ProjectModel projectModel = projectDao.getModelById(project_id, true);
        if (projectModel == null) {
            FrameUtil.throwBaseException1("请求的记录不存在！");
        }

        if(projectModel.getOrg_id().intValue()!=org_id.intValue()){
            FrameUtil.throwBaseException1("该项目不属于当前机构");
        }

        List<ProjectRateModel> rateList = config.getRateList();
        Map rateMap = new HashMap();
        for (ProjectRateModel model : rateList) {
            if (model.getRate() == null || model.getRate().intValue() == 0) {
                FrameUtil.throwBaseException1("请配置" + model.getLimit() + "期数利率");
            }
            rateMap.put(model.getLimit().toString(), model.getRate().toString());
        }

        Long currtime = FrameUtil.getTime(null);
        if (this.projectDao.updateByMap(FrameUtil.newHashMap("project_id", project_id, "rate_config", JSON.toJSONString(rateMap),
                "last_update_time", currtime), true) != 1) {
            FrameUtil.throwBaseException1("更新利率失败！");
        }
        merchantChangeLogsService.insert(new MerchantChangeLogsModel(projectModel.getOrg_id(),
                "商户更新利率配置，项目id：" + project_id + "  利率配置：" + JSON.toJSONString(rateMap), currtime));
        return 1;
    }

    @Resource
    private ITagRelevanceService tagRelevanceService;

    @Resource
    private IIntroDetailDao introDetailDao;

    @Resource
    private IOrganizationService organizationService;

    @Resource
    private IPrjCategoryService prjCategoryService;

    @Resource
    private ITagService tagService;

    @Resource
    private IProjectDao projectDao;

    @Resource
    private IMerchantChangeLogsService merchantChangeLogsService;

    @Override
    public IBaseDao getBaseDao() {
        return this.projectDao;
    }

}
